package com.shzg.im.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;

import com.shzg.im.model.ApiResult;
import com.shzg.im.model.Category;
import com.shzg.im.model.CategoryFriend;
import com.shzg.im.model.Group;
import com.shzg.im.model.User;
import com.shzg.im.service.GroupService;
import com.shzg.im.service.UserService;

@RestController
@RequestMapping("/user")
@Transactional
@SessionAttributes("user")
public class UserController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private GroupService groupService;

    @RequestMapping("/logout")
    public ModelAndView logout(SessionStatus ss) {
        ss.setComplete();
        ModelAndView mv = new ModelAndView("redirect:/shzg_im", "command", new User());
        return mv;
    }

    @RequestMapping("/logout/{json}")
    public ApiResult logout(SessionStatus ss, String json) {
        ss.setComplete();
        return ApiResult.RST_OK;
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ApiResult login() {
        System.out.println("login please");
        ApiResult apiRst = ApiResult.RST_NOK;
        apiRst.setObj("Login please");
        return apiRst;
    }

    @RequestMapping(value = "/login/{json}", method = RequestMethod.POST)
    public ApiResult login(@ModelAttribute("SpringWeb") User user, HttpSession ses, @PathVariable String json) {
        System.out.println("login user : " + user);
        User u = userService.getUser(user.getLoginId());
        String msg = "old user: " + user.getLoginId();
        ApiResult apiRst = null;
        Map<String, String> userInfoMap = new HashMap<String, String>();
        if (u == null) {
            userService.saveUser(user);
            msg = "new user: " + user.getLoginId();
            ses.setAttribute("user", user);
        } else {
            ses.setAttribute("user", u);
        }

        userInfoMap.put("loginId", user.getLoginId());
        userInfoMap.put("nickName", user.getNickName());
        userInfoMap.put("avatar", user.getAvatar());
        userInfoMap.put("description", user.getDescription());

        apiRst = new ApiResult(0, "ok", userInfoMap);
        return apiRst;
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public View login(@ModelAttribute("SpringWeb") User user, HttpSession ses) {
        System.out.println("login user : " + user);
        ses.setAttribute("user", user);
        User u = userService.getUser(user.getLoginId());
        String msg = "old user: " + user.getLoginId();
        if (u == null) {
            userService.saveUser(user);
            msg = "new user: " + user.getLoginId();
            ses.setAttribute("user", user);
        } else {
            ses.setAttribute("user", u);
        }
        return new RedirectView("/shzg_im");
    }

    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
    public ApiResult getUser(@PathVariable String userId) {
        ApiResult apiRst = ApiResult.RST_OK;
        Map<String, String> userInfoMap = new HashMap<String, String>();
        User user = userService.getUser(userId);
        if (user != null) {
            userInfoMap.put("loginId", user.getLoginId());
            userInfoMap.put("nickName", user.getNickName());
            userInfoMap.put("avatar", user.getAvatar());
            userInfoMap.put("description", user.getDescription());
        }
        apiRst.setObj(userInfoMap);
        return apiRst;
    }

    @RequestMapping(value = "", method = RequestMethod.GET)
    public ApiResult getUser(@ModelAttribute User user) {
        ApiResult apiRst = ApiResult.RST_OK;
        Map<String, String> userInfoMap = new HashMap<String, String>();

        userInfoMap.put("loginId", user.getLoginId());
        userInfoMap.put("nickName", user.getNickName());
        userInfoMap.put("avatar", user.getAvatar());
        userInfoMap.put("description", user.getDescription());

        apiRst.setObj(userInfoMap);
        return apiRst;
    }

    @RequestMapping("list")
    public ModelAndView list() {
        List<User> userList = userService.getUserList();
        return new ModelAndView("user/list", "userList", userList);
    }

    @RequestMapping(value = "/login/{loginId}/{password}")
    public ApiResult login(@PathVariable String loginId, @PathVariable String password) {
        return new ApiResult(0, "ok", "login ok: " + loginId + " " + password);
    }

    @RequestMapping(value = "/friend/add")
    public ApiResult addFriends(@ModelAttribute User user, @RequestParam("destUserId") String destUserId,
            @RequestParam("catId") String catId) {
        ApiResult apiResult = ApiResult.RST_OK;

        userService.addFriend(user.getLoginId(), destUserId, catId);

        if (StringUtils.isEmpty(catId)) {
            catId = Category.NONCATEGORY_ID;
        }
        Map<String, String> respMap = new HashMap<String, String>();
        respMap.put("destUserId", destUserId);
        respMap.put("catId", catId);

        apiResult.setObj(respMap);

        return apiResult;
    }

    @RequestMapping(value = "/friend/del/{friId}", method = RequestMethod.POST)
    public ApiResult delFriends(@ModelAttribute User user, @PathVariable String friId) {
        ApiResult apiResult = ApiResult.RST_OK;

        userService.removeFriend(user.getLoginId(), friId);

        return apiResult;
    }

    @RequestMapping(value = "/friends")
    public ApiResult getFriends(@ModelAttribute User user) {
        ApiResult apiResult = new ApiResult();

        List<Category> catLst = userService.getCategoryWithFriendByUserId(user.getLoginId());

        List<Map<String, Object>> rstCatLst = new LinkedList<Map<String, Object>>();

        for (Category cat : catLst) {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("name", cat.getName());
            dataMap.put("nums", cat.getFriendList().size());
            dataMap.put("id", cat.getId());
            List<Map> freLst = new ArrayList<Map>();
            for (CategoryFriend catFre : cat.getFriendList()) {
                Map<String, Object> freMap = new HashMap<String, Object>();
                freMap.put("id", catFre.getLoginId());
                freMap.put("name", StringUtils.isEmpty(catFre.getNickName()) ? catFre.getLoginId() : catFre.getNickName());
                freMap.put("face", catFre.getAvatar());
                freLst.add(freMap);
            }
            dataMap.put("item", freLst);
            rstCatLst.add(dataMap);
        }

        apiResult.setObj(rstCatLst);

        return apiResult;
    }

    @RequestMapping("/groups")
    public ApiResult getGroup(@ModelAttribute User user) {
        ApiResult apiResult = new ApiResult();

        List<Group> grpLst = groupService.getGroupListByMemberId(user.getLoginId());

        Map<String, Object> grpMap = new LinkedHashMap<String, Object>();

        grpMap.put("name", "My Groups");
        grpMap.put("nums", grpLst.size());
        grpMap.put("id", "MyGroups");

        List<Map<String, Object>> rstGrpLst = new ArrayList<Map<String, Object>>();

        for (Group g : grpLst) {
            Map<String, Object> grpInfoMap = new LinkedHashMap<String, Object>();

            grpInfoMap.put("id", g.getId());
            grpInfoMap.put("name", g.getName());
            grpInfoMap.put("face", g.getAvatar());

            rstGrpLst.add(grpInfoMap);
        }

        grpMap.put("item", rstGrpLst);

        apiResult.setObj(new Object[] { grpMap });

        return apiResult;
    }

    @RequestMapping(value = "/profile", method = RequestMethod.GET)
    public ModelAndView profileSettings(@ModelAttribute User user) {
        return new ModelAndView("user/profile_setting", "user", user);
    }

    @RequestMapping(value = "/profile", method = RequestMethod.POST)
    public ApiResult profileSettingsSave(@ModelAttribute("SpringWeb") User user, @ModelAttribute User sesUser) {

        ApiResult apiRst = new ApiResult();

        System.out.println("Saved user " + user);

        user.setLoginId(sesUser.getLoginId());

        userService.updateUser(user);

        apiRst.setObj(user.toString());

        return apiRst;
    }

    @RequestMapping(value = "search/{keywords}", method = RequestMethod.GET)
    public ApiResult searchUser(@PathVariable String keywords, @ModelAttribute User user) {
        ApiResult apiRst = new ApiResult();
        List<User> usrLst = userService.searchUser(keywords);

        List<Map<String, String>> usrInfoLst = new ArrayList<Map<String, String>>();
        Set<String> usrIdSet = new HashSet<String>();
        for (User u : usrLst) {
            if (usrIdSet.contains(u.getLoginId()) == false) {
                usrIdSet.add(u.getLoginId());
            } else {
                // 若包含用户的ID则跳过， 去重
                continue;
            }
            if (u.getLoginId().equalsIgnoreCase(user.getLoginId())) {
                // 不需要自己在用户列表中
                continue;
            }
            Map<String, String> usrInfoMap = new HashMap<String, String>();
            usrInfoMap.put("loginId", u.getLoginId());
            usrInfoMap.put("avatar", u.getAvatar());
            usrInfoMap.put("nickName", StringUtils.isEmpty(u.getNickName()) ? u.getLoginId() : u.getNickName());
            usrInfoLst.add(usrInfoMap);
        }

        apiRst.setObj(usrInfoLst);

        return apiRst;
    }

    @RequestMapping(value = "/hello/{id}")
    public String test(@PathVariable String id) {
        ApiResult apiResult = new ApiResult();
        return id;
    }
}
